package com.educatioin.manage.wechat.service;

import com.educatioin.manage.common.beans.Response;
import com.educatioin.manage.constant.OrderStatus;
import com.educatioin.manage.constant.WeChatApiConstant;
import com.educatioin.manage.web.productorder.po.ProductOrderPo;
import com.educatioin.manage.web.productorder.repository.ProductOrderRepository;
import com.educatioin.manage.web.schoolgradeclass.po.SchoolGradeClassPo;
import com.educatioin.manage.web.schoolgradeclass.repository.SchoolGradeClassRepository;
import com.educatioin.manage.web.system.po.CustomerPo;
import com.educatioin.manage.web.system.po.LoginHistoryPo;
import com.educatioin.manage.web.system.repository.CustomerRepository;
import com.educatioin.manage.web.system.repository.LoginHistoryRepository;
import com.educatioin.manage.wechat.dto.OrderInfoDto;
import com.educatioin.manage.wechat.dto.UnifiedOrderReq;
import com.educatioin.manage.wechat.request.CreateOrderReq;
import com.educatioin.manage.wechat.response.CreateOrderRsp;
import com.educatioin.manage.wechat.response.QueryOrdersRsp;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * Created by zhangchen on 2018/4/19.
 */
@Service
public class WeChatOrderService {

    @Resource
    private ProductOrderRepository productOrderRepository;
    @Resource
    private CustomerRepository customerRepository;
    @Resource
    private WeChatPayService weChatPayService;
    @Resource
    private LoginHistoryRepository loginHistoryRepository;
    @Resource
    private SchoolGradeClassRepository schoolGradeClassRepository;

    @Transactional
    public QueryOrdersRsp queryOrdersByToken(HttpServletRequest request){
        QueryOrdersRsp queryOrdersRsp = new QueryOrdersRsp();

        Object token = request.getSession().getAttribute("token");
        if(null == token){
            queryOrdersRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            queryOrdersRsp.setReturnMsg("客户未登录！");
            return queryOrdersRsp;
        }
        //根据token找到已登录用户
        LoginHistoryPo loginHistoryPo = loginHistoryRepository.findByToken(token.toString());
        if(null == loginHistoryPo){
            queryOrdersRsp.setReturnCode(Response.RETURN_FAIL_CODE);
            queryOrdersRsp.setReturnMsg("客户未登录！");
            return queryOrdersRsp;
        }

        String phone = loginHistoryPo.getCustomerName();
        //获取所有订单
        List<ProductOrderPo> allOrders = productOrderRepository.findByPhone(phone);

        List<OrderInfoDto> alls = Lists.newArrayList();
        List<OrderInfoDto> unpays = Lists.newArrayList();
        List<OrderInfoDto> applies = Lists.newArrayList();
        List<OrderInfoDto> pays = Lists.newArrayList();
        List<OrderInfoDto> completes = Lists.newArrayList();

        if(CollectionUtils.isEmpty(allOrders)){
            return queryOrdersRsp;
        }

        for(ProductOrderPo productOrderPo : allOrders){
            OrderInfoDto orderInfoDto = new OrderInfoDto();

            orderInfoDto.setOrderCode(productOrderPo.getOrderCode());
            orderInfoDto.setOrderImage(productOrderPo.getProductImage());
            orderInfoDto.setProductName(productOrderPo.getProductName());
            orderInfoDto.setOrderStatus(OrderStatus.valueOf(productOrderPo.getOrderStatus()).getDescription());
            orderInfoDto.setGroupName(productOrderPo.getGroupName());
            orderInfoDto.setPhone(phone);
            orderInfoDto.setSchoolGradeClazz(productOrderPo.getSchool() + "," + productOrderPo.getGrade() + "," + productOrderPo.getClazz());
            orderInfoDto.setProductDeposit(productOrderPo.getProductDeposit());

            if(OrderStatus.UN_PAYED.name().equals(productOrderPo.getOrderStatus())){
                unpays.add(orderInfoDto);
            }else if(OrderStatus.ORDERED.name().equals(productOrderPo.getOrderStatus())){
                applies.add(orderInfoDto);
            }else if(OrderStatus.PAYED.name().equals(productOrderPo.getOrderStatus())){
                pays.add(orderInfoDto);
            }else if(OrderStatus.COMPLETE.name().equals(productOrderPo.getOrderStatus())){
                completes.add(orderInfoDto);
            }

            alls.add(orderInfoDto);
        }

        queryOrdersRsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
        queryOrdersRsp.setAlls(alls);
        queryOrdersRsp.setApplies(applies);
        queryOrdersRsp.setUnPays(unpays);
        queryOrdersRsp.setPays(pays);
        queryOrdersRsp.setCompletes(completes);
        return queryOrdersRsp;
    }

    @Transactional
    public void updateOrderStatus(String orderCode, String orderStatus){
        ProductOrderPo productOrderPo = productOrderRepository.findByOrderCode(orderCode);
        if(null == productOrderPo){
            return;
        }

        productOrderPo.setOrderStatus(orderStatus);
        productOrderRepository.save(productOrderPo);

        String code = productOrderPo.getRecommenderCode();
        //推荐人增加积分
        if(StringUtils.isBlank(productOrderPo.getRecommenderCode())){
            SchoolGradeClassPo schoolGradeClassPo = schoolGradeClassRepository.findByschoolNameAndGradeAndClazz(productOrderPo.getSchool(), productOrderPo.getGrade(), productOrderPo.getClazz());
            if(null==schoolGradeClassPo){
                return;
            }
            code = schoolGradeClassPo.getRecommenderIds();
        }

        CustomerPo customerPo = customerRepository.findByPhone(code);
        if(null == customerPo){
            return;
        }
        customerPo.setPoint(customerPo.getPoint() + productOrderPo.getProductDeposit());
        customerRepository.save(customerPo);
    }

    @Transactional
    public CreateOrderRsp createOrder(CreateOrderReq req){
        CreateOrderRsp rsp = new CreateOrderRsp();

        ProductOrderPo productOrderPo = new ProductOrderPo();
        productOrderPo.setProductImage(req.getProductImage());
        productOrderPo.setProductName(req.getProductName());
        productOrderPo.setProductCode(req.getProductCode());
        productOrderPo.setProductDeposit(req.getProductDeposit());
        productOrderPo.setApplicantName(req.getApplicantName());
        productOrderPo.setGroupName(req.getGroupName());
        productOrderPo.setPhone(req.getPhone());
        productOrderPo.setProductType(req.getProductType());

        productOrderPo.setSchool(req.getSchoolGradeClazz().split(",")[0]);
        productOrderPo.setGrade(req.getSchoolGradeClazz().split(",")[1]);
        productOrderPo.setClazz(req.getSchoolGradeClazz().split(",")[2]);
        productOrderPo.setRecommenderCode(req.getRecommenderCode());

        productOrderPo.setOrderCode(getOrderCodeByTime());
        productOrderPo.setOrderStatus(OrderStatus.UN_PAYED.name());
        productOrderPo.setRequestIp(req.getRequestIp());
        productOrderPo.setOpenid(req.getOpenid());
        productOrderPo.setCreateTime(System.currentTimeMillis());

        productOrderRepository.save(productOrderPo);

        //是否为第一次购买
        String phone = req.getPhone();
        CustomerPo customerPo = customerRepository.findByPhone(phone);
        if(null == customerPo){
            customerPo = new CustomerPo();
            customerPo.setType(CustomerPo.CUSTOMER_TYPE);
            customerPo.setCode(getCustomerCode());
            //默认账号密码与手机号一致
            customerPo.setName(phone);
            customerPo.setPassword(getSHA256Str(phone));
            customerPo.setPhone(phone);
            customerPo.setCreateTime(System.currentTimeMillis());
            customerPo.setCreateUser("admin");
            customerPo.setEnabled(true);
            SchoolGradeClassPo schoolGradeClassPo = schoolGradeClassRepository.findByschoolNameAndGradeAndClazz(productOrderPo.getSchool(), productOrderPo.getGrade(), productOrderPo.getClazz());
            if(null!=schoolGradeClassPo){
                customerPo.setSchoolGradeClassId(schoolGradeClassPo.getId());
            }
            customerRepository.save(customerPo);
        }

        rsp.setReturnCode(Response.RETURN_SUCCESS_CODE);
        rsp.setOrderCode(productOrderPo.getOrderCode());
        return rsp;
    }

    @Transactional
    public boolean getPrepaidIdByOder(ProductOrderPo orderPo){
        //向微信api获取预付id;
        UnifiedOrderReq unifiedOrderReq = new UnifiedOrderReq();
        unifiedOrderReq.setBody(orderPo.getProductName());
        unifiedOrderReq.setOutTradeNo(orderPo.getOrderCode());
        unifiedOrderReq.setDeviceInfo("WEB");
        unifiedOrderReq.setTotalFee(orderPo.getProductDeposit()*100);
        unifiedOrderReq.setSpbillCreateIp(orderPo.getRequestIp());
        unifiedOrderReq.setNotifyUrl(WeChatApiConstant.NOTIFY_URI);
        unifiedOrderReq.setTradeType(WeChatApiConstant.TRADE_TYPE);
        unifiedOrderReq.setOpenid(orderPo.getOpenid());
        Map<String,String> unifiedOrderResult = weChatPayService.unifiedOrder(unifiedOrderReq);

        //获取预付id失败
        if(null==unifiedOrderResult||"FAIL".equals(unifiedOrderResult.get("return_code"))){
            return false;
        }
        //写入预付id
        orderPo.setPrepayId(unifiedOrderResult.get("prepay_id"));
        return true;
    }

    private String getOrderCodeByTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String newDate = sdf.format(new Date());
        String result = "";
        Random random = new Random();
        for(int i = 0; i < 3; i++){
            result += random.nextInt(10);
        }
        return newDate + result;
    }

    private String getCustomerCode() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String newDate = sdf.format(new Date());
        String result = "";
        Random random = new Random();
        for(int i = 0; i < 5; i++){
            result += random.nextInt(10);
        }
        return newDate + result;
    }

    private String getSHA256Str(String str){
        MessageDigest messageDigest;
        String encdeStr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] hash = messageDigest.digest(str.getBytes("UTF-8"));
            encdeStr = Hex.encodeHexString(hash);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encdeStr;
    }
}
